#ifndef EXPRESSIONVALUE
#define EXPRESSIONVALUE

#include "ExpressionType.hpp"

/**
    @brief classe de valeur d'une expression

    représente la classe de valeur d'une expression (ie : indique si on doit  accéder à la mémoire locale)
    - E opbin E --> CE_VALUE (+,/,*,<,>,<=,>=,==,!=,&&,||)
    - opun E --> CE_VALUE (-,!)
    - & E --> CE_VALUE
    - * E --> CE_MEMORY
    - E [ E ] --> CE_MEMORY
    - identificateur --> CE_MEMORY
    - appel de fonction --> CE_VALUE
*/
typedef enum
{
    CE_MEMORY, /**< valeur en mémoire */
    CE_VALUE /**< valeur constante */
} ExpressionClass;

inline std::ostream& operator<< ( std::ostream& out, ExpressionClass vclass )
{
    switch ( vclass )
    {
    case CE_MEMORY:
        out << "CE_MEMORY";
        break;
    case CE_VALUE:
        out << "CE_VALUE";
        break;
    }
    return out;
}

/**
    @brief valeur d'une expression

    les différentes valeurs effectives que peut prendre une expression
*/
typedef union
{
    int _vinteger; /**< constante entiere */
    float _vreal; /**< constante réelle */
    bool _vboolean; /**< constante booléenne */
    char* _vstring; /**< chaine de caractère */
    unsigned int _vaddress; /**< référence à une adresse dans la mémoire locale du contexte en cours d'exécution */
} Value;

inline std::ostream& operator<< ( std::ostream& out, Value value )
{
    out << "(" << value._vinteger << "," << value._vreal << "," << value._vboolean << "," << value._vaddress << ")";
    return out;
}

/**
    @brief valeur typée

    représente la valeur typée d'une expression

*/
typedef struct
{
    ExpressionClass _class; /**< classe de l'expression */
    Type _type; /**< type de la valeur */
    Value _value; /**< valeur de l'expression */
} ExpressionValue;

inline std::ostream& operator<< ( std::ostream& out, ExpressionValue vexpr )
{
    out << "{" << vexpr._class << "," << vexpr._type << "," << vexpr._value << "}";
    return out;
}

#endif


